﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using System.Timers;
using System.ComponentModel;
using System.Configuration;
using System.Windows.Media;

namespace Indigo.Quibbler.Controls
{
    public partial class AdsControl : UserControl
    {
        #region Private Members
        private DispatcherTimer timer = null;
        private string _adsUrl = string.Empty;
        private bool _cacheEnabled = false;
        #endregion

        #region Properties
        public string ImageUrl
        {
            get { return (string)GetValue(ImageUrlProperty); }
            set { SetValue(ImageUrlProperty, value); }
        }
        public static readonly DependencyProperty ImageUrlProperty =
            DependencyProperty.Register("ImageUrl", typeof(string), typeof(AdsControl), new UIPropertyMetadata(string.Empty, OnImageUrlChanged));


        public string OfflineUrl
        {
            get { return (string)GetValue(OfflineUrlProperty); }
            set { SetValue(OfflineUrlProperty, value); }
        }


        public static readonly DependencyProperty OfflineUrlProperty =
            DependencyProperty.Register("OfflineUrl", typeof(string), typeof(AdsControl), new UIPropertyMetadata(""));


        #endregion

        #region Ctor
        public AdsControl()
        {
            InitializeComponent();
            _cacheEnabled = _GetIsCacheEnabled();

            timer = new DispatcherTimer();
            timer.Tick += new EventHandler(timer_Tick);
            int interval = 30;
            try
            {
                interval = int.Parse(ConfigurationSettings.AppSettings["Ads.RefreshTimerInSecs"]);
            }
            catch { interval = 30; }
            timer.Interval = TimeSpan.FromSeconds(interval);
            timer.Start();
            adsImage.MouseDown += new MouseButtonEventHandler(_AdsCliked);
        }
        #endregion

        #region Event Handlers
        void timer_Tick(object sender, EventArgs e)
        {
            // Optimization: Avoid internet requests when control is not visible
            if (this.Visibility != Visibility.Visible)
                return;

            try
            {
                string url = ImageUrl;

                if (!string.IsNullOrEmpty(url))
                {
                    string imageUrl = _GetImageUrl(url);
                    if (_GetIsCacheEnabled())
                    {
                        // CASE: When caching is enabled, looks for image in local cache before downloading
                        try
                        {
                            string adsCacheDir = Path.Combine(Utilities.DataStorePath, "Ads");
                            if (!Directory.Exists(adsCacheDir))
                                Directory.CreateDirectory(adsCacheDir);

                            string fileKey = imageUrl.GetHashCode().ToString();
                            string filePath = Path.Combine(adsCacheDir, fileKey);
                            if (!File.Exists(filePath))
                            {
                                WebClient downloader = new WebClient();
                                downloader.DownloadFileCompleted -= new AsyncCompletedEventHandler(downloader_DownloadFileCompleted);
                                downloader.DownloadFileCompleted += new AsyncCompletedEventHandler(downloader_DownloadFileCompleted);
                                downloader.DownloadFileAsync(new Uri(imageUrl, UriKind.Absolute), filePath, filePath);
                            }
                            else
                            {
                                adsImage.Source = new BitmapImage(new Uri((string)filePath, UriKind.RelativeOrAbsolute));
                                adsImage.Visibility = Visibility.Visible;
                            }
                        }
                        catch (Exception ex)
                        {
                            _cacheEnabled = false;
                            throw;  // Handle error in the main catch
                        }
                    }
                    else
                    {
                        // CASE: Cache not enabled. Images are downloaded on the fly.
                        WebRequest request = WebRequest.Create(imageUrl);
                        using (WebResponse response = request.GetResponse())
                        {
                            using (Stream stream = response.GetResponseStream())
                            {
                                System.Drawing.Image image = System.Drawing.Image.FromStream(stream);
                                using (MemoryStream imageStream = new MemoryStream())
                                {
                                    image.Save(imageStream, System.Drawing.Imaging.ImageFormat.Png);
                                    adsImage.Source = BitmapFrame.Create(imageStream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
                                    adsImage.Visibility = Visibility.Visible;
                                }
                                stream.Close();
                            }
                            response.Close();
                        }
                    }
                }
                else
                {
                    _HandleError();
                }
            }
            catch (Exception ex)
            {
                _HandleError();
                Utilities.Log("AdControl Error: ", ex);
            }
        }

        void downloader_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            if (!e.Cancelled)
            {
                adsImage.Source = new BitmapImage(new Uri((string)e.UserState, UriKind.RelativeOrAbsolute));
                adsImage.Visibility = Visibility.Visible;
            }
            else
                _HandleError();
        }
        #endregion

        #region Dependency Members
        private static void OnImageUrlChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            (obj as AdsControl).OnImageUrlChanged(e);
        }
        private void OnImageUrlChanged(DependencyPropertyChangedEventArgs e)
        {
            try
            {
                adsImage.Source = new BitmapImage(new Uri(OfflineUrl, UriKind.RelativeOrAbsolute));
                adsImage.Visibility = Visibility.Visible;
                notAvailableText.Visibility = Visibility.Hidden;
            }
            catch
            {
                adsImage.Visibility = Visibility.Hidden;
                notAvailableText.Visibility = Visibility.Visible;
            }
        }
        #endregion

        #region Helper Functions
        void _AdsCliked(object sender, MouseButtonEventArgs e)
        {
            try
            {
                if (_adsUrl != string.Empty)
                {
                    System.Diagnostics.Process.Start(_adsUrl);
                }
                else
                {
                    if (this.Name == "adsControlTop")
                    {
                        System.Diagnostics.Process.Start("http://www.airtel.in/");
                    }
                    else if (this.Name == "adsControlBottom")
                    {
                        System.Diagnostics.Process.Start("http://www.alibaba.com/");
                    }
                }
            }
            catch { }
        }

        private void _HandleError()
        {
            try
            {
                adsImage.Source = new BitmapImage(new Uri(OfflineUrl, UriKind.RelativeOrAbsolute));
                adsImage.Visibility = Visibility.Visible;
                notAvailableText.Visibility = Visibility.Hidden;
            }
            catch
            {
                adsImage.Visibility = Visibility.Hidden;
                notAvailableText.Visibility = Visibility.Visible;
            }

        }
        public string _GetImageUrl(string url)
        {
            try
            {
                WebRequest request = WebRequest.Create(url);
                request.Timeout = 1000;
                WebResponse response = request.GetResponse();
                Stream stream = response.GetResponseStream();
                StreamReader reader = new StreamReader(stream);
                string htmlText = reader.ReadToEnd();
                Match match = Regex.Match(htmlText, @"<img src=""(?<URL>[^""]+)""");
                string imageUrl = match.Groups["URL"].Value;

                try
                {
                    match = Regex.Match(htmlText, @"<a href=""(?<URL>[^""]+)""");
                    _adsUrl = match.Groups["URL"].Value;
                }
                catch { _adsUrl = string.Empty; }


                reader.Close();
                stream.Close();
                response.Close();
                return imageUrl;
            }
            catch
            {
                return string.Empty;
            }
        }

        private static bool _GetIsCacheEnabled()
        {
            try { return bool.Parse(ConfigurationSettings.AppSettings["Ads.EnableCache"]); }
            catch { }

            return false;
        }
        #endregion
    }
}
